package com.webamc.util;

import org.apache.log4j.Logger;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Date: Mar 18, 2009
 * Time: 11:59:34 PM
 */
public class AuthUtil {
    private static final Logger log = Logger.getLogger(AuthUtil.class);
    private static AuthUtil authUtil;
    private static Passwords p;
    private static final int pvtKey = 0x54563456;

    private static final class Passwords {
        private final Map<Integer, char[]> passwords = new HashMap<Integer, char[]>();

        public synchronized void add(int userId, char[] password) {
            passwords.put(userId, password);
            DB4OUtil.update(passwords); //persist
            log.info("persisted authentication for - userId=" + userId);
        }

        public synchronized boolean matches(int userId, char[] password) {
            return Arrays.equals(password, passwords.get(userId));
        }

        public synchronized void remove(int userId) {
            passwords.remove(userId);
            DB4OUtil.update(passwords); //persist
            log.info("persisted authentication after removing - userId=" + userId);
        }

        public synchronized int size() {
            return passwords.size();
        }

        public boolean exists(int userId) {
            return passwords.containsKey(userId);
        }
    }

    private AuthUtil() {
        List<Passwords> passList = DB4OUtil.getAll(Passwords.class);
        if (passList.size() == 1) {
            p = passList.get(0);
            log.warn("found passwords mapping .. loading complete");
        } else if (passList.size() == 0) {
            log.warn("no passwords mapping found, trying adding empty mapping.");
            p = new Passwords();
            DB4OUtil.insert(p);//System wide singleton
        } else {
            p = passList.get(0);
            log.warn("multiple passwords mapping found, using first entry.");
        }
    }

    public static AuthUtil instance() {
        if (authUtil == null) {
            synchronized (AuthUtil.class) {
                if (authUtil == null) {
                    authUtil = new AuthUtil();
                    log.info("Singleton class AuthUtil initialized.");
                }
            }
        }

        return authUtil;
    }

    public void remove(int userId, int funcKey) {
        if (funcKey == pvtKey) {
            p.remove(userId);
        }
    }

    public void add(int userId, char[] password, int funcKey) {
        if (funcKey == pvtKey) {
            p.add(userId, password);
        }
    }

    public boolean matches(int userId, char[] password, int funcKey) {
        return funcKey == pvtKey && p.matches(userId, password);
    }

    public int size() {
        return p.size();
    }
}
